package com.ca.ridersclubapplication.request;

import android.app.Activity;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.ca.ridersclubapplication.data.DataHandler;
import com.ca.ridersclubapplication.request.dto.AccountCardDto;
import com.ca.ridersclubapplication.request.dto.AccountDto;
import com.ca.ridersclubapplication.data.entity.BooleanEntity;
import com.ca.ridersclubapplication.data.entity.ListEntity;
import com.ca.ridersclubapplication.data.entity.LongEntity;
import com.ca.ridersclubapplication.data.entity.Token;
import com.ca.ridersclubapplication.request.dto.AccountUpdateDto;
import com.ca.ridersclubapplication.request.dto.Result;
import com.ca.ridersclubapplication.view.card.AccountCard;

import java.util.List;

import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.Query;

public class AccountRequester {

    public static String URL = "account/";

    public static final AccountAPI api;

    static {
        api = new Retrofit.Builder()
                .baseUrl(Config.BASE_URL + URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(AccountAPI.class);
    }

    public interface AccountAPI {

        @POST("register")
        @FormUrlEncoded
        Call<Result<AccountDto>> register(
                @Field("email") String email,
                @Field("code") String code,
                @Field("nickname") String nickname,
                @Field("gender") String gender,
                @Field("password") String password);

        @GET("get")
        Call<Result<AccountDto>> getAccount(@Query("id") long id);

        @GET("getIdByEmail")
        Call<Result<Long>> getIdByEmail(@Query("email") String email);

        @GET("nickname")
        Call<Result<AccountDto>> nickname(@Query("nickname") String nickname);

        @POST("update")
        @FormUrlEncoded
        Call<Result<AccountDto>> update(
                @Field("id") Long id,
                @Field("nickname") String nickname,
                @Field("gender") String gender,
                @Field("birth") String birth,
                @Field("city") String city,
                @Field("profile") String profile,
                @Field("createTime") String createTime,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("getFollows")
        Call<Result<List<AccountCardDto>>> getFollows(
                @Query("accountId") Long accountId,
                @Query("startId") Long startId);

        @GET("getFans")
        Call<Result<List<AccountCardDto>>> getFans(
                @Query("accountId") Long accountId,
                @Query("startId") Long startId);

        @GET("getFollowCount")
        Call<Result<Long>> getFollowCount(@Query("accountId") Long accountId);

        @GET("getFansCount")
        Call<Result<Long>> getFansCount(@Query("accountId") Long accountId);

        @POST("addFollow")
        @FormUrlEncoded
        Call<Result<String>> addFollow(
                @Field("accountId") Long accountId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("deleteFollow")
        @FormUrlEncoded
        Call<Result<String>> deleteFollow(
                @Field("accountId") Long accountId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("isFollow")
        Call<Result<Boolean>> isFollow(
                @Query("id") Long id,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("addBlack")
        @FormUrlEncoded
        Call<Result<String>> addBlack(
                @Field("targetId") Long targetId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @POST("removeBlack")
        @FormUrlEncoded
        Call<Result<String>> removeBlack(
                @Field("targetId") Long targetId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("isBlack")
        Call<Result<Boolean>> isBlack(
                @Query("targetId") Long targetId,
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);

        @GET("listBlack")
        Call<Result<List<AccountDto>>> listBlack(
                @Header("Authorization") String token,
                @Header("arg0") String hid,
                @Header("arg1") String email);
    }

    public static void register(Activity activity, TextView tipView, String email, String code, String nickname, String gender, String password, AfterExecutor<AccountDto> executor) {
        api.register(email, code, nickname, gender, password)
                .enqueue(new APICallback<AccountDto>(activity, tipView, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<AccountDto>> call, @NonNull Response<Result<AccountDto>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            //  注册成功
                            Toast.makeText(getActivity(), "注册成功", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }

    public static void getAccount(Activity activity, Long id, AfterExecutor<AccountDto> executor) {
        api.getAccount(id)
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void getIdByEmail(Activity activity, String email, AfterExecutor<Long> executor) {
        api.getIdByEmail(email)
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void getAccountByNickname(Activity activity, String nickname, AfterExecutor<AccountDto> executor) {
        api.nickname(nickname).enqueue(new APICallback<>(activity, executor));
    }

    public static void updateAccount(Activity activity, AccountUpdateDto dto, AfterExecutor<AccountDto> executor) {
        Token token = DataHandler.getToken(activity);
        api.update(
                dto.getId(),
                dto.getNickname(),
                dto.getGender(),
                dto.getBirth(),
                "",
                dto.getProfile(),
                dto.getTime(),
                token.getToken(),
                String.valueOf(token.getId()),
                token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void listFollow(Activity activity, Long accountId, Long startId, AfterExecutor<List<AccountCardDto>> executor) {
        api.getFollows(accountId, startId)
                .enqueue(new APICallback<List<AccountCardDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<AccountCardDto>>> call, @NonNull Response<Result<List<AccountCardDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            List<AccountCardDto> list = getData();
                            DataHandler.putData(new ListEntity<>("AccountFollowsList:" + accountId, list));
                            DataHandler.putData(new LongEntity("AccountFollowCount:" + accountId, list == null ? 0L : list.size()));
                        }
                    }
                });
    }

    public static void listFans(Activity activity, Long accountId, Long startId, AfterExecutor<List<AccountCardDto>> executor) {
        api.getFans(accountId, startId)
                .enqueue(new APICallback<List<AccountCardDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<AccountCardDto>>> call, @NonNull Response<Result<List<AccountCardDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            List<AccountCardDto> list = getData();
                            DataHandler.putData(new ListEntity<>("AccountFansList:" + accountId, list));
                            DataHandler.putData(new LongEntity("AccountFansCount:" + accountId, list == null ? 0L : list.size()));
                        }
                    }
                });
    }

    public static void getFollowCount(Activity activity, Long accountId, AfterExecutor<Long> executor) {
        api.getFollowCount(accountId)
                .enqueue(new APICallback<Long>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<Long>> call, @NonNull Response<Result<Long>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            Long count = getData();
                            DataHandler.putData(new LongEntity("AccountFollowCount:" + accountId, count));
                        }
                    }
                });
    }

    public static void getFansCount(Activity activity, Long accountId, AfterExecutor<Long> executor) {
        api.getFansCount(accountId)
                .enqueue(new APICallback<Long>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<Long>> call, @NonNull Response<Result<Long>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            Long count = getData();
                            DataHandler.putData(new LongEntity("AccountFansCount:" + accountId, count));
                        }
                    }
                });
    }

    public static void addFollow(Activity activity, Long accountId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.addFollow(accountId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void deleteFollow(Activity activity, Long accountId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.deleteFollow(accountId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void isFollow(Activity activity, Long accountId, AfterExecutor<Boolean> executor) {
        Token token = DataHandler.getToken(activity);
        api.isFollow(accountId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<Boolean>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<Boolean>> call, @NonNull Response<Result<Boolean>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new BooleanEntity(
                                    "AccountIsFollow:" + token.getId() + ":" + accountId,
                                    getData()));
                        }
                    }
                });
    }

    public static void addBlack(Activity activity, Long targetId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.addBlack(targetId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void removeBlack(Activity activity, Long targetId, AfterExecutor<String> executor) {
        Token token = DataHandler.getToken(activity);
        api.removeBlack(targetId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<>(activity, executor));
    }

    public static void isBlack(Activity activity, Long accountId, AfterExecutor<Boolean> executor) {
        Token token = DataHandler.getToken(activity);
        api.isBlack(accountId, token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<Boolean>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<Boolean>> call, @NonNull Response<Result<Boolean>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new BooleanEntity(
                                    "AccountIsBlack:" + token.getId() + ":" + accountId,
                                    getData()));
                        }
                    }
                });
    }

    public static void listBlack(Activity activity, AfterExecutor<List<AccountDto>> executor) {
        Token token = DataHandler.getToken(activity);
        api.listBlack(token.getToken(), String.valueOf(token.getId()), token.getEmail())
                .enqueue(new APICallback<List<AccountDto>>(activity, executor) {
                    @Override
                    public void onResponse(@NonNull Call<Result<List<AccountDto>>> call, @NonNull Response<Result<List<AccountDto>>> response) {
                        super.onResponse(call, response);
                        if (isSuccess()) {
                            DataHandler.putData(new ListEntity<>("AccountBlackList:" + token.getId(), getData()));
                        }
                    }
                });
    }
}
